// 文件路径: dbms/parser/SqlParser.java
package com.dbms.parser;

import com.dbms.catalogInParse.Column;
import com.dbms.common.Constants;
import com.dbms.common.Position;
import com.dbms.common.SqlError;
import com.dbms.parser.ast.*;

import java.util.*;

/**
 * SQL语法分析器，负责将词法分析器生成的Token流转换为抽象语法树（AST）。
 * <p>
 * 这个类采用递归下降的解析策略，为每一种SQL语句或子句都提供一个解析方法。
 * 它会按顺序消费Token，并根据SQL的语法规则构建一个层次化的AST节点结构。
 * 如果遇到语法错误，它能够报告错误并尝试恢复，继续解析后续的语句。
 * <p>
 * 【已修改】
 * 增强了对 CREATE TABLE 语句中 FOREIGN KEY 子句的解析能力。
 */
public class SqlParser {
    /**
     * 从词法分析器接收的Token列表。
     */
    private final List<Token> tokens;
    /**
     * 指向当前正在处理的Token在列表中的索引。
     */
    private int currentPosition;
    /**
     * 存储在解析过程中遇到的所有语法错误。
     */
    private final List<SqlError> errors = new ArrayList<>();
    /**
     * 一个标志，指示当前是否处于错误状态，用于错误恢复。
     */
    private boolean hasError = false;

    /**
     * SqlParser的构造函数。
     *
     * @param tokens 从SqlLexer获得的Token列表。
     */
    public SqlParser(List<Token> tokens) {
        this.tokens = tokens;
        this.currentPosition = 0;
    }

    /**
     * 解析所有Token，直到文件结束符（EOF）。
     * 这是解析器的入口点，可以处理包含多条SQL语句的脚本。
     *
     * @return 一个包含所有成功解析的语句的AST节点列表。
     */
    public List<StatementNode> parseAll() {
        List<StatementNode> statements = new ArrayList<>();
        // 只要还没到Token流的末尾就继续循环
        while (peek().getType() != TokenType.EOF) {
            StatementNode stmt = parseStatement();
            if (stmt != null) {
                statements.add(stmt);
            }
            // 如果在解析上一条语句时发生了错误
            if (hasError) {
                // 尝试跳过当前错误语句，找到下一条语句的开始
                if (!skipToNextStatement()) {
                    // 如果无法找到下一条语句（比如已经到了文件末尾），则中断解析
                    break;
                }
            }
        }
        return statements;
    }

    /**
     * 解析单个SQL语句。
     * 这是一个分发方法，它会查看当前的Token来决定应该调用哪个具体的语句解析方法。
     *
     * @return 如果成功解析，则返回对应的 {@link StatementNode}，否则返回null。
     */
    private StatementNode parseStatement() {
        Token currentToken = peek();
        if (currentToken.getType() == TokenType.EOF) return null;

        // 根据第一个关键字决定调用哪个解析函数
        switch (currentToken.getLexeme().toUpperCase()) {
            case "CREATE":
                // CREATE 后面可能是 TABLE 或 USER
                if (lookAhead(1).getLexeme().equalsIgnoreCase("TABLE")) {
                    return parseCreateTable();
                } else if (lookAhead(1).getLexeme().equalsIgnoreCase("USER")) {
                    return parseCreateUser();
                } else {
                    handleSyntaxError("期望 'TABLE' 或 'USER' 跟在 'CREATE' 之后");
                    return null;
                }
            case "INSERT": return parseInsert();
            case "SELECT": return parseSelect();
            case "DELETE": return parseDelete();
            case "UPDATE": return parseUpdate();
            case "BACKUP": return parseBackup();
            case "DROP": return parseDropUser();
            case "GRANT": return parseGrant();
            case "REVOKE": return parseRevoke();
            case "BEGIN": return parseBegin();
            case "COMMIT": return parseCommitOrRollback(TransactionNode.Command.COMMIT);
            case "ROLLBACK": return parseCommitOrRollback(TransactionNode.Command.ROLLBACK);
            case "EXPLAIN": return parseExplain();
            default:
                handleSyntaxError("未知或不支持的语句开头: '" + currentToken.getLexeme() + "'");
                return null;
        }
    }

    /**
     * 在语句节点构建完成后，设置其结束位置。
     *
     * @param node 已构建的语句节点。
     */
    private void finalizeStatementNode(StatementNode node) {
        if (node != null) {
            // 将节点的结束索引设置为上一个消费的Token的结束索引
            node.getPosition().setEndIndex(previous().getPosition().getEndIndex());
        }
    }

    /**
     * 解析 CREATE TABLE 语句。
     *
     * @return 一个 {@link CreateTableNode} 实例。
     */
    private CreateTableNode parseCreateTable() {
        Position startPos = peek().getPosition();
        consumeAndExpect("CREATE");
        consumeAndExpect("TABLE");

        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望表名"); return null; }
        String tableName = consume().getLexeme();

        consumeAndExpect("(");
        List<Column> columns = new ArrayList<>();
        List<ForeignKeyNode> foreignKeys = new ArrayList<>();
        // 解析括号内的列定义和约束
        if (!parseColumnAndConstraintDefinitions(columns, foreignKeys)) return null;
        consumeAndExpect(")");
        consumeAndExpect(";");

        CreateTableNode node = new CreateTableNode(startPos, tableName, columns, foreignKeys);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 CREATE TABLE 语句括号内的列定义和外键约束。
     *
     * @param columns     用于存储解析出的列定义的列表。
     * @param foreignKeys 用于存储解析出的外键约束的列表。
     * @return 如果解析成功返回 true。
     */
    private boolean parseColumnAndConstraintDefinitions(List<Column> columns, List<ForeignKeyNode> foreignKeys) {
        do {
            // 判断当前是列定义还是外键约束
            if (match("FOREIGN")) {
                ForeignKeyNode fk = parseForeignKey();
                if (fk == null) return false;
                foreignKeys.add(fk);
            } else {
                if (!parseColumn(columns)) return false;
            }
            // 如果后面有逗号，则继续循环解析下一个定义
        } while (match(",") && consume() != null);
        return true;
    }

    /**
     * 解析单个列的定义。
     * 例如 `id INT PRIMARY KEY` 或 `name VARCHAR(50)`。
     *
     * @param columns 用于存储解析出的列定义的列表。
     * @return 如果解析成功返回 true。
     */
    private boolean parseColumn(List<Column> columns) {
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望列名"); return false; }
        String colName = consume().getLexeme();

        if (!matchType(TokenType.TYPE)) { handleSyntaxError("期望数据类型 (如 INT, VARCHAR)"); return false; }
        String colType = consume().getLexeme();

        int varcharLength = 0;
        // 如果是 VARCHAR 类型，则解析其长度
        if (colType.equalsIgnoreCase("VARCHAR") && match("(")) {
            consume();
            if (!matchType(TokenType.CONSTANT)) {
                handleSyntaxError("期望 VARCHAR 类型的长度，例如 VARCHAR(100)");
                return false;
            }
            try {
                varcharLength = Integer.parseInt(consume().getLexeme());
            } catch (NumberFormatException e) {
                handleSyntaxError("VARCHAR 长度必须是一个有效的数字");
                return false;
            }
            consumeAndExpect(")");
        }

        boolean isPrimary = false;
        // 检查是否有 PRIMARY KEY 约束
        if (match("PRIMARY")) {
            consume();
            consumeAndExpect("KEY");
            isPrimary = true;
        }

        columns.add(new Column(colName, colType, isPrimary, varcharLength));
        return true;
    }

    /**
     * 解析 FOREIGN KEY 约束子句。
     *
     * @return 一个 {@link ForeignKeyNode} 实例。
     */
    private ForeignKeyNode parseForeignKey() {
        consumeAndExpect("FOREIGN");
        consumeAndExpect("KEY");
        consumeAndExpect("(");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望外键列名"); return null; }
        String sourceColumn = consume().getLexeme();
        consumeAndExpect(")");
        consumeAndExpect("REFERENCES");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望引用的表名"); return null; }
        String refTable = consume().getLexeme();
        consumeAndExpect("(");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望引用的列名"); return null; }
        String refColumn = consume().getLexeme();
        consumeAndExpect(")");
        return new ForeignKeyNode(sourceColumn, refTable, refColumn);
    }

    /**
     * 解析 INSERT INTO 语句。
     *
     * @return 一个 {@link InsertNode} 实例。
     */
    private InsertNode parseInsert() {
        Position startPos = peek().getPosition();
        consumeAndExpect("INSERT");
        consumeAndExpect("INTO");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望表名"); return null; }
        String tableName = consume().getLexeme();
        consumeAndExpect("VALUES");
        consumeAndExpect("(");
        List<String> values = new ArrayList<>();
        // 解析值列表
        if (!parseValueList(values)) return null;
        consumeAndExpect(")");
        consumeAndExpect(";");

        // 注意：这里简化了处理，没有解析列名列表（如 INSERT INTO t(c1, c2)）
        InsertNode node = new InsertNode(startPos, tableName, new ArrayList<>(), values);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 VALUES 子句中的值列表。
     *
     * @param values 用于存储解析出的值的列表。
     * @return 如果解析成功返回 true。
     */
    private boolean parseValueList(List<String> values) {
        if (!matchType(TokenType.CONSTANT)) { handleSyntaxError("期望常量值"); return false; }
        values.add(consume().getLexeme());

        // 如果有逗号，继续解析
        while(match(",")) {
            consume();
            if (!matchType(TokenType.CONSTANT)) { handleSyntaxError("期望逗号后的常量值"); return false; }
            values.add(consume().getLexeme());
        }
        return true;
    }

    /**
     * 解析 SELECT 语句，支持多种复杂的子句。
     *
     * @return 一个 {@link SelectNode} 实例。
     */
    private SelectNode parseSelect() {
        Position startPos = peek().getPosition();
        consumeAndExpect("SELECT");
        List<Object> columns = new ArrayList<>();
        // 解析选择列表 (e.g., id, name or *)
        if (!parseSelectList(columns)) return null;
        consumeAndExpect("FROM");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望表名"); return null; }
        String tableName = consume().getLexeme();

        // 顺序解析可选的子句
        JoinNode joinNode = match("JOIN") ? parseJoin() : null;
        ExpressionNode whereClause = match("WHERE") ? parseWhere() : null;
        GroupByNode groupByNode = match("GROUP") ? parseGroupBy() : null;
        ExpressionNode havingClause = match("HAVING") ? parseHaving() : null;
        OrderByNode orderByNode = match("ORDER") ? parseOrderBy() : null;
        LimitNode limitNode = match("LIMIT") ? parseLimit() : null;
        consumeAndExpect(";");

        SelectNode node = new SelectNode(startPos, columns, tableName, whereClause, joinNode, groupByNode, orderByNode, limitNode, havingClause);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 LIMIT 子句。
     *
     * @return 一个 {@link LimitNode} 实例。
     */
    private LimitNode parseLimit() {
        consumeAndExpect("LIMIT");
        if (!matchType(TokenType.CONSTANT)) {
            handleSyntaxError("LIMIT 后面需要一个数字");
            return null;
        }
        int firstVal = Integer.parseInt(consume().getLexeme());

        // 处理 LIMIT offset, count 的情况
        if (match(",")) {
            consume();
            if (!matchType(TokenType.CONSTANT)) {
                handleSyntaxError("LIMIT <offset>, 后面需要一个数字");
                return null;
            }
            int secondVal = Integer.parseInt(consume().getLexeme());
            return new LimitNode(secondVal, firstVal); // (limit, offset)
        }

        // 处理 LIMIT count 的情况
        return new LimitNode(firstVal, 0);
    }

    /**
     * 解析 HAVING 子句。
     *
     * @return 一个 {@link ExpressionNode} 实例。
     */
    private ExpressionNode parseHaving() {
        consumeAndExpect("HAVING");
        return parseAggregateExpression();
    }

    /**
     * 解析 HAVING 子句中的聚合表达式，例如 `COUNT(*) > 5`。
     *
     * @return 一个 {@link ExpressionNode} 实例。
     */
    private ExpressionNode parseAggregateExpression() {
        // HAVING 子句必须以一个函数调用开始
        FunctionCallNode funcCall = parseFunctionCall();
        if (funcCall == null) {
            handleSyntaxError("HAVING 子句需要以聚合函数开头");
            return null;
        }
        String left = funcCall.toString(); // e.g. "COUNT(*)"

        if (!matchType(TokenType.OPERATOR)) { handleSyntaxError("期望运算符"); return null; }
        String op = consume().getLexeme();

        Object right;
        if (matchType(TokenType.CONSTANT)) {
            String rightStr = consume().getLexeme();
            try { right = Integer.parseInt(rightStr); }
            catch (NumberFormatException e) { right = rightStr.replaceAll("^'|'$", ""); }
        } else {
            handleSyntaxError("HAVING 子句运算符后期望一个常量");
            return null;
        }
        return new ExpressionNode(left, op, right);
    }

    /**
     * 解析 SELECT 后的列/项列表。
     *
     * @param columns 用于存储解析出的项的列表 (可以是字符串列名，'*'，或函数调用节点)。
     * @return 如果解析成功返回 true。
     */
    private boolean parseSelectList(List<Object> columns) {
        if (match("*")) {
            columns.add(consume().getLexeme());
        } else {
            if (!parseSelectItem(columns)) return false;
            while (match(",")) {
                consume();
                if (!parseSelectItem(columns)) return false;
            }
        }
        return true;
    }

    /**
     * 解析 SELECT 列表中的单个项，可能是列名或函数调用。
     *
     * @param columns 用于存储解析出的项的列表。
     * @return 如果解析成功返回 true。
     */
    private boolean parseSelectItem(List<Object> columns) {
        if (!matchType(TokenType.IDENTIFIER)) {
            handleSyntaxError("期望列名, '*' 或函数调用");
            return false;
        }

        // 通过向前看一个Token是否是'('来区分是函数调用还是普通列名
        if (lookAhead(1).getLexeme().equals("(")) {
            FunctionCallNode funcCall = parseFunctionCall();
            if (funcCall == null) return false;
            columns.add(funcCall);
        } else {
            columns.add(consume().getLexeme());
        }
        return true;
    }

    /**
     * 解析一个函数调用，例如 `COUNT(*)` 或 `UPPER(name)`。
     *
     * @return 一个 {@link FunctionCallNode} 实例。
     */
    private FunctionCallNode parseFunctionCall() {
        String functionName = consume().getLexeme();
        consumeAndExpect("(");

        List<Object> arguments = new ArrayList<>();
        if (!match(")")) { // 如果不是空参数列表
            do {
                if (match("*")) {
                    arguments.add(consume().getLexeme());
                } else if (matchType(TokenType.IDENTIFIER)) {
                    arguments.add(consume().getLexeme());
                } else if (matchType(TokenType.CONSTANT)) {
                    String constant = consume().getLexeme();
                    try {
                        arguments.add(Integer.parseInt(constant));
                    } catch (NumberFormatException e) {
                        arguments.add(constant.replaceAll("^'|'$", ""));
                    }
                } else {
                    handleSyntaxError("函数参数必须是 '*', 标识符或常量");
                    return null;
                }
            } while (match(",") && consume() != null); // 如果有逗号，继续解析下一个参数
        }

        consumeAndExpect(")");
        return new FunctionCallNode(functionName, arguments);
    }

    /**
     * 解析 WHERE 关键字，并调用表达式解析器。
     *
     * @return 一个代表WHERE条件的 {@link ExpressionNode}。
     */
    private ExpressionNode parseWhere() {
        consumeAndExpect("WHERE");
        return parseExpression();
    }

    /**
     * 解析 DELETE 语句。
     *
     * @return 一个 {@link DeleteNode} 实例。
     */
    private DeleteNode parseDelete() {
        Position startPos = peek().getPosition();
        consumeAndExpect("DELETE");
        consumeAndExpect("FROM");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望表名"); return null; }
        String tableName = consume().getLexeme();
        ExpressionNode whereClause = match("WHERE") ? parseWhere() : null;
        consumeAndExpect(";");

        DeleteNode node = new DeleteNode(startPos, tableName, whereClause);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析一个通用表达式，主要用于WHERE和SET子句。
     * 支持 `column = column + 5` 这种算术形式。
     *
     * @return 一个 {@link ExpressionNode} 实例。
     */
    private ExpressionNode parseExpression() {
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("表达式必须以列名开头"); return null; }
        String left = consume().getLexeme();

        if (!matchType(TokenType.OPERATOR)) { handleSyntaxError("期望运算符"); return null; }
        String op = consume().getLexeme();
        // 特殊情况处理: `SET balance = balance + 100`
        if (op.equals("=") &&
                lookAhead(0).getType() == TokenType.IDENTIFIER &&
                lookAhead(0).getLexeme().equalsIgnoreCase(left) &&
                (lookAhead(1).getLexeme().equals("+") || lookAhead(1).getLexeme().equals("-")) &&
                lookAhead(2).getType() == TokenType.CONSTANT) {

            String rightColumn = consume().getLexeme();
            String arithmeticOp = consume().getLexeme();
            String constantStr = consume().getLexeme();
            Object value;
            try {
                value = Integer.parseInt(constantStr);
            } catch (NumberFormatException e) {
                value = constantStr.replaceAll("^'|'$", "");
            }

            ArithmeticNode arithmeticNode = new ArithmeticNode(rightColumn, arithmeticOp, value);
            return new ExpressionNode(left, op, arithmeticNode);
        }
        // 通用情况处理: `column op value` or `column op column`
        Object right;
        if (matchType(TokenType.CONSTANT)) {
            String rightStr = consume().getLexeme();
            try { right = Integer.parseInt(rightStr); }
            catch (NumberFormatException e) { right = rightStr.replaceAll("^'|'$", ""); }
        } else if (matchType(TokenType.IDENTIFIER)) {
            right = consume().getLexeme();
        } else {
            handleSyntaxError("运算符后期望常量或标识符");
            return null;
        }
        return new ExpressionNode(left, op, right);
    }

    /**
     * 解析 UPDATE 语句。
     *
     * @return 一个 {@link UpdateNode} 实例。
     */
    private UpdateNode parseUpdate() {
        Position startPos = peek().getPosition();
        consumeAndExpect("UPDATE");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望表名"); return null; }
        String tableName = consume().getLexeme();
        consumeAndExpect("SET");

        List<ExpressionNode> setClause = new ArrayList<>();
        do {
            ExpressionNode expr = parseExpression();
            if (expr == null) return null;
            setClause.add(expr);
        } while (match(",") && consume() != null); // 支持多个 SET 表达式

        ExpressionNode whereClause = match("WHERE") ? parseWhere() : null;
        consumeAndExpect(";");

        UpdateNode node = new UpdateNode(startPos, tableName, setClause, whereClause);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 JOIN 子句。
     *
     * @return 一个 {@link JoinNode} 实例。
     */
    private JoinNode parseJoin() {
        consumeAndExpect("JOIN");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望表名"); return null; }
        String rightTable = consume().getLexeme();
        consumeAndExpect("ON");
        ExpressionNode onCondition = parseExpression();
        return new JoinNode("JOIN", rightTable, onCondition);
    }

    /**
     * 解析 GROUP BY 子句。
     *
     * @return 一个 {@link GroupByNode} 实例。
     */
    private GroupByNode parseGroupBy() {
        consumeAndExpect("GROUP");
        consumeAndExpect("BY");
        List<String> columns = new ArrayList<>();
        do {
            if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望列名"); return null; }
            columns.add(consume().getLexeme());
        } while (match(",") && consume() != null); // 支持按多列分组
        return new GroupByNode(columns);
    }

    /**
     * 解析 ORDER BY 子句。
     *
     * @return 一个 {@link OrderByNode} 实例。
     */
    private OrderByNode parseOrderBy() {
        consumeAndExpect("ORDER");
        consumeAndExpect("BY");
        List<String> columns = new ArrayList<>();
        do {
            if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望列名"); return null; }
            columns.add(consume().getLexeme());
        } while (match(",") && consume() != null); // 支持按多列排序

        String order = "ASC"; // 默认为升序
        if (match("ASC") || match("DESC")) {
            order = consume().getLexeme().toUpperCase();
        }
        return new OrderByNode(columns, order);
    }

    /**
     * 解析 BACKUP DATABASE 语句。
     *
     * @return 一个 {@link BackupNode} 实例。
     */
    private BackupNode parseBackup() {
        Position startPos = peek().getPosition();
        consumeAndExpect("BACKUP");
        consumeAndExpect("DATABASE");
        consumeAndExpect("TO");
        if (!matchType(TokenType.CONSTANT)) { handleSyntaxError("期望备份文件路径"); return null; }
        String filePath = consume().getLexeme();
        consumeAndExpect(";");

        BackupNode node = new BackupNode(startPos, filePath);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 CREATE USER 语句。
     *
     * @return 一个 {@link CreateUserNode} 实例。
     */
    private CreateUserNode parseCreateUser() {
        Position startPos = peek().getPosition();
        consumeAndExpect("CREATE");
        consumeAndExpect("USER");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望用户名"); return null; }
        String username = consume().getLexeme();
        consumeAndExpect("IDENTIFIED");
        consumeAndExpect("BY");
        if (!matchType(TokenType.CONSTANT)) { handleSyntaxError("期望密码"); return null; }
        String password = consume().getLexeme();
        consumeAndExpect(";");

        CreateUserNode node = new CreateUserNode(startPos, username, password);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 DROP USER 语句。
     *
     * @return 一个 {@link DropUserNode} 实例。
     */
    private DropUserNode parseDropUser() {
        Position startPos = peek().getPosition();
        consumeAndExpect("DROP");
        consumeAndExpect("USER");
        if (!matchType(TokenType.IDENTIFIER)) { handleSyntaxError("期望用户名"); return null; }
        String username = consume().getLexeme();
        consumeAndExpect(";");

        DropUserNode node = new DropUserNode(startPos, username);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 GRANT 语句。
     *
     * @return 一个 {@link GrantNode} 实例。
     */
    private GrantNode parseGrant() {
        Position startPos = peek().getPosition();
        consumeAndExpect("GRANT");
        String privilege = consume().getLexeme().toUpperCase();
        consumeAndExpect("ON");
        String tableName = consume().getLexeme();
        consumeAndExpect("TO");
        String userName = consume().getLexeme();
        consumeAndExpect(";");

        GrantNode node = new GrantNode(startPos, privilege, tableName, userName);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 REVOKE 语句。
     *
     * @return 一个 {@link RevokeNode} 实例。
     */
    private RevokeNode parseRevoke() {
        Position startPos = peek().getPosition();
        consumeAndExpect("REVOKE");
        String privilege = consume().getLexeme().toUpperCase();
        consumeAndExpect("ON");
        String tableName = consume().getLexeme();
        consumeAndExpect("FROM");
        String userName = consume().getLexeme();
        consumeAndExpect(";");

        RevokeNode node = new RevokeNode(startPos, privilege, tableName, userName);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 BEGIN TRANSACTION 语句。
     *
     * @return 一个 {@link TransactionNode} 实例。
     */
    private TransactionNode parseBegin() {
        Position startPos = peek().getPosition();
        consumeAndExpect("BEGIN");
        // "TRANSACTION" 关键字是可选的
        if (match("TRANSACTION")) consume();
        consumeAndExpect(";");

        TransactionNode node = new TransactionNode(startPos, TransactionNode.Command.BEGIN);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 COMMIT 或 ROLLBACK 语句。
     *
     * @param command 命令类型 (COMMIT or ROLLBACK)。
     * @return 一个 {@link TransactionNode} 实例。
     */
    private TransactionNode parseCommitOrRollback(TransactionNode.Command command) {
        Position startPos = peek().getPosition();
        consumeAndExpect(command.name());
        consumeAndExpect(";");

        TransactionNode node = new TransactionNode(startPos, command);
        finalizeStatementNode(node);
        return node;
    }

    /**
     * 解析 EXPLAIN 或 EXPLAIN ANALYZE 语句。
     *
     * @return 一个 {@link ExplainNode} 实例。
     */
    private ExplainNode parseExplain() {
        Position startPos = peek().getPosition();
        consumeAndExpect("EXPLAIN");
        // 检查是否有 ANALYZE 关键字
        boolean isAnalyze = match("ANALYZE") && consume() != null;

        // EXPLAIN 后面跟着的是一个完整的SQL语句，所以我们递归调用 parseStatement
        StatementNode statementToExplain = parseStatement();
        if (statementToExplain == null) return null;

        ExplainNode node = new ExplainNode(startPos, statementToExplain, isAnalyze);
        // 手动设置结束位置，因为它包含了子语句
        node.getPosition().setEndIndex(statementToExplain.getPosition().getEndIndex());
        return node;
    }

    /**
     * 消费一个Token并验证其词素是否与期望值匹配。
     *
     * @param expectedLexeme 期望的词素字符串。
     */
    private void consumeAndExpect(String expectedLexeme) {
        if (!match(expectedLexeme)) {
            handleSyntaxError("期望 '" + expectedLexeme + "'");
        } else {
            consume();
        }
    }

    /**
     * 处理语法错误。
     *
     * @param message 错误信息。
     */
    private void handleSyntaxError(String message) {
        if (hasError) return; // 只报告第一个遇到的错误，避免级联错误
        Token current = peek();
        String errorMsg = message + "，但实际得到的是 '" + (current != null ? current.getLexeme() : "EOF") + "'";
        errors.add(new SqlError(Constants.ErrorType.SYNTAX_ERROR, current != null ? current.getPosition() : new Position(0,0,0), errorMsg));
        hasError = true;
    }

    /**
     * 错误恢复：尝试跳过当前错误的语句，直到找到下一个分号。
     *
     * @return 如果成功找到下一个语句的开始，返回 true。
     */
    private boolean skipToNextStatement() {
        while (peek().getType() != TokenType.EOF) {
            if (match(";")) {
                consume();
                hasError = false; // 重置错误标志，准备解析新语句
                return true;
            }
            consume();
        }
        return false;
    }

    /**
     * 检查当前Token的词素是否与给定字符串匹配（不区分大小写）。
     *
     * @param lexeme 要匹配的字符串。
     * @return 如果匹配返回 true。
     */
    private boolean match(String lexeme) {
        if (peek().getType() == TokenType.EOF) return false;
        return peek().getLexeme().equalsIgnoreCase(lexeme);
    }

    /**
     * 检查当前Token的类型是否与给定类型匹配。
     *
     * @param type 要匹配的 {@link TokenType}。
     * @return 如果匹配返回 true。
     */
    private boolean matchType(TokenType type) {
        if (peek().getType() == TokenType.EOF) return false;
        return peek().getType() == type;
    }

    /**
     * 消费当前Token并返回上一个Token。
     *
     * @return 被消费的上一个Token。
     */
    private Token consume() {
        if (!isAtEnd()) currentPosition++;
        return previous();
    }

    /**
     * 向前查看指定偏移量的Token，但不移动当前指针。
     *
     * @param offset 偏移量。
     * @return 目标位置的Token。
     */
    private Token lookAhead(int offset) {
        if (currentPosition + offset >= tokens.size()) {
            return tokens.get(tokens.size() - 1); // 返回EOF
        }
        return tokens.get(currentPosition + offset);
    }

    /**
     * 检查是否已到达Token流的末尾。
     *
     * @return 如果是末尾则返回 true。
     */
    private boolean isAtEnd() {
        return currentPosition >= tokens.size();
    }

    /**
     * 查看当前位置的Token，但不移动指针。
     *
     * @return 当前Token。
     */
    private Token peek() {
        if (currentPosition >= tokens.size()) {
            return tokens.get(tokens.size()  - 1); // 返回EOF
        }
        return tokens.get(currentPosition);
    }

    /**
     * 获取上一个被消费的Token。
     *
     * @return 上一个Token。
     */
    private Token previous() {
        return tokens.get(currentPosition - 1);
    }

    /**
     * 获取在解析过程中遇到的所有错误。
     *
     * @return 一个包含 {@link SqlError} 的列表。
     */
    public List<SqlError> getErrors() {
        return errors;
    }
}